package com.derbysoft.dswitch.adapter.ihg.web.action.admin.setting.hotel;

import com.derbysoft.dswitch.adapter.ihg.common.domain.HotelMapping;
import com.derbysoft.dswitch.adapter.ihg.common.domain.HotelStatus;
import com.derbysoft.dswitch.adapter.ihg.common.repository.HotelRepository;
import com.derbysoft.dswitch.adapter.ihg.exception.HotelNotFoundException;
import com.derbysoft.dswitch.adapter.ihg.web.action.DMXAbstractAction;
import com.opensymphony.xwork2.ActionContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * User: jason
 * Date: 2013-01-22
 */
public class DMXAction extends DMXAbstractAction {
    private static final int MAX_LINES = 500;

    @Autowired
    private HotelRepository hotelRepository;

    private HotelMapping hotelMapping;

    private String hotels;

    private String disableHotelCodes;

    private String deleteHotelCode;

    @Action("dmxQueryHotel")
    public String dmxQuery() {
        try {
            ActionContext.getContext().setLocale(ServletActionContext.getRequest().getLocale());
            setPaginater(hotelRepository.paginater(hotelMapping, getPaginater()));
            return populateSucceededJsonResult(dmxPaging());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxImportHotels")
    public String importHotels() {
        try {
            if (StringUtils.isBlank(hotels)) {
                return populateSucceededJsonResult("nothing to import.");
            }
            Map<String, HotelMapping> hotelMappingMap = new HashMap<String, HotelMapping>();
            StringBuilder builder = new StringBuilder();
            String[] lines = hotels.replace("\r\n", "\n").split("\n");
            for (int lineNumber = 0; lineNumber < lines.length && lineNumber < MAX_LINES; lineNumber++) {
                String[] columns = lines[lineNumber].split("\\|");
                if (columns == null || (columns.length != 2 && columns.length != 3)) {
                    builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\">[ %d ]. error line :[ %s ]</span>", lineNumber + 1, lines[lineNumber])).append("<br>");
                    continue;
                }
                String[] trimmedColumns = trimAll(columns);
                String hotelCode = trimmedColumns[0];
                String passport = trimmedColumns[1];
                String hotelName = trimmedColumns[2];
                HotelMapping loadByCode = hotelRepository.loadByHotelCode(hotelCode);
                HotelMapping loadByPassport = hotelRepository.loadByDerbyCode(passport);
                if (loadByCode != null || loadByPassport != null) {
                    if (loadByCode != null) {
                        builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\"> HotelCode [ %s ] has been existed !!</span>", hotelCode)).append("<br>");
                        continue;
                    }
                    if (loadByPassport != null) {
                        builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\"> Passport [ %s ] has been existed !!</span>", passport)).append("<br>");
                    }
                    continue;
                }

                HotelMapping newMapping = new HotelMapping();
                newMapping.setCooperatorCode(hotelCode);
                newMapping.setDerbyCode(passport);
                newMapping.setHotelName(hotelName);
                newMapping.setStatus(HotelStatus.ENABLED);
                hotelMappingMap.put(hotelCode, newMapping);
                builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">[ %s ] : successful !!</span>", hotelCode)).append("<br>");
            }
            builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">-------------  total:[%d], successful:[%d] -------------</span>", lines.length, hotelMappingMap.values().size())).append("<br>");
            hotelRepository.saveAll(new ArrayList<HotelMapping>(hotelMappingMap.values()));
            return populateSucceededJsonResult(builder.toString());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxBatchDisable")
    public String dmxBatchDisable() {
        try {
            if (StringUtils.isBlank(disableHotelCodes)) {
                return populateSucceededJsonResult("nothing to disable.");
            }
            Map<String, HotelMapping> hotelMappingMap = new HashMap<String, HotelMapping>();
            StringBuilder builder = new StringBuilder();
            String[] hotelCodes = StringUtils.split(disableHotelCodes, " ");
            for (String hotelCode : hotelCodes) {
                HotelMapping existed = hotelRepository.loadByHotelCode(hotelCode);
                if (existed == null) {
                    builder.append(String.format("<span style=\"color: #ff0000;font-family:Consolas;font-weight: bold;\"> Hotel not found :[ %s ] !!</span>", hotelCode)).append("<br>");
                    continue;
                }
                builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">[ %s ]: disable done !!</span>", hotelCode)).append("<br>");
                hotelMappingMap.put(hotelCode, existed);
            }
            hotelRepository.disableAll(new ArrayList<HotelMapping>(hotelMappingMap.values()));
            builder.append(String.format("<span style=\"color: #0000ff;font-family:Consolas;font-weight: bold;\">-------------  total:[%d], successful:[%d] -------------</span>", hotelCodes.length, hotelMappingMap.values().size())).append("<br>");
            return populateSucceededJsonResult(builder.toString());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxDeleteHotel")
    public String dmxDeleteHotel() {
        try {
            if (StringUtils.isBlank(deleteHotelCode)) {
                return populateSucceededJsonResult("hotel code must be not null.");
            }
            HotelMapping existed = hotelRepository.loadByHotelCode(deleteHotelCode);
            if (existed == null) {
                throw new HotelNotFoundException(deleteHotelCode);
            }
            hotelRepository.delete(existed);
            return populateSucceededJsonResult(String.format("delete done [%s].", deleteHotelCode));
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxLoadHotel")
    public String dmxLoadHotel() {
        try {
            if (hotelMapping==null||StringUtils.isBlank(hotelMapping.getCooperatorCode())) {
                return populateSucceededJsonResult("hotel code must be not null !");
            }
            HotelMapping existed = hotelRepository.loadByHotelCode(hotelMapping.getCooperatorCode());
            if (existed == null) {
                throw new HotelNotFoundException(hotelMapping.getCooperatorCode());
            }
            return populateSucceededJsonResult(existed);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxUpdateHotel")
    public String dmxUpdateHotel() {
        try {
            if (hotelMapping==null) {
                return populateSucceededJsonResult("hotel must be not null !");
            }
            HotelMapping existed = hotelRepository.loadByHotelCode(hotelMapping.getCooperatorCode());
            if (existed == null) {
                throw new HotelNotFoundException(hotelMapping.getCooperatorCode());
            }
            existed.setDerbyCode(hotelMapping.getDerbyCode());
            existed.setHotelName(hotelMapping.getHotelName());
            existed.setStatus(hotelMapping.getStatus());
            hotelRepository.save(existed);
            return populateSucceededJsonResult(existed);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    private String[] trimAll(String[] columns) {
        String[] newColumns = new String[columns.length];
        for (int i = 0; i < columns.length; i++) {
            newColumns[i] = StringUtils.trim(columns[i]);
        }
        return newColumns;
    }

    public String getDeleteHotelCode() {
        return deleteHotelCode;
    }

    public void setDeleteHotelCode(String deleteHotelCode) {
        this.deleteHotelCode = deleteHotelCode;
    }

    public String getDisableHotelCodes() {
        return disableHotelCodes;
    }

    public void setDisableHotelCodes(String disableHotelCodes) {
        this.disableHotelCodes = disableHotelCodes;
    }

    public HotelMapping getHotelMapping() {
        return hotelMapping;
    }

    public void setHotelMapping(HotelMapping hotelMapping) {
        this.hotelMapping = hotelMapping;
    }

    public String getHotels() {
        return hotels;
    }

    public void setHotels(String hotels) {
        this.hotels = hotels;
    }
}
